#include "mem_utils.h"

struct _m_mallco_dev mallco_dev=
{
 mem_init, 
 mem_perused,
 0,   
 0,   
 0,     
};

void mem_memcpy(void *des,void *src,u32 n)  
{  
    u8 *xdes=des;
		u8 *xsrc=src; 
    while(n--)*xdes++=*xsrc++;  
}  

void mem_memset(void *s,u8 c,u32 count)  
{  
    u8 *xs = s;  
    while(count--)*xs++=c;  
}    
 
void mem_init(void)  
{  
    mem_memset(mallco_dev.membase, 0, sizeof(mallco_dev.membase)); 
    mallco_dev.memrdy=1; 
}  

u8 mem_perused(void)  
{  
    u16 used=0;  
    u32 i;  
    for(i=0;i<MEM_ALLOC_TABLE_SIZE;i++)  
    {  
        if(mallco_dev.memmap)used++; 
    }  
    return used*100/MEM_ALLOC_TABLE_SIZE;  
}  
 
u32 mem_malloc(u32 size)  
{  
    signed long offset=0;  
    u16 nmemb; 
 u16 cmemb=0;
    u32 i;  
    if(!mallco_dev.memrdy)mallco_dev.init();
    if(size==0)return 0XFFFFFFFF;
    nmemb=size/MEM_BLOCK_SIZE;   
    if(size%MEM_BLOCK_SIZE)nmemb++;  
    for(offset=MEM_ALLOC_TABLE_SIZE-1;offset>=0;offset--) 
    {     
  if(!mallco_dev.memmap[offset])cmemb++; 
  else cmemb=0;       
  if(cmemb==nmemb)     
  {
            for(i=0;i<nmemb;i++)     
            {  
                mallco_dev.memmap[offset+i]=nmemb;  
            }  
            return (offset*MEM_BLOCK_SIZE); 
  }
    }  
    return 0XFFFFFFFF;
}  
 
u8 mem_free(u32 offset)  
{  
    int i;  
    if(!mallco_dev.memrdy)
 {
  mallco_dev.init();    
        return 1; 
    }  
    if(offset<MAX_MEM_SIZE)
    {  
        int index=offset/MEM_BLOCK_SIZE; 
        int nmemb=mallco_dev.memmap[index]; 
        for(i=0;i<nmemb;i++)     
        {  
            mallco_dev.memmap[index+i]=0;  
        }  
        return 0;  
    }else return 2; 
}  

void myfree(void *ptr)  
{  
 u32 offset;  
    if(ptr==NULL)return; 
    offset=(u32)ptr-(u32)&mallco_dev.membase;  
    mem_free(offset);   
}  

void *mymalloc(u32 size)  
{  
    u32 offset;  
    offset=mem_malloc(size);  
    if(offset==0XFFFFFFFF)return NULL;  
    else return (void*)((u32)&mallco_dev.membase+offset);  
}  

void *myrealloc(void *ptr,u32 size)  
{  
    u32 offset;  
    offset=mem_malloc(size);  
    if(offset==0XFFFFFFFF)return NULL;     
    else  
    {  
        mem_memcpy((void*)((u32)&mallco_dev.membase+offset),ptr,size);  
        myfree(ptr);               
        return (void*)((u32)&mallco_dev.membase+offset);        
    }  
}

/**
int main(void)
{    
 u8 *ptr;
 u16 *ptr1;
 u32 *ptr2;
  u32 *ptr3;

 u8 i;
   Stm32_Clock_Init(9);//??????
 delay_init(72);  //?????
 uart_init(72,9600); //??1???  
 LED_Init();
  //LCD_Init();  
 ptr=(u8*)mymalloc(100);
 if(*ptr)i=0;
 i=mallco_dev.perused();//?????
 ptr1=(u16*)mymalloc(2*100);
 i=mallco_dev.perused();//?????
 ptr2=(u32*)mymalloc(4*100);
 i=mallco_dev.perused();//?????
 myfree(ptr); 
 i=mallco_dev.perused();//?????
 ptr3=(u32*)mymalloc(4*20);
 i=mallco_dev.perused();//?????
 myfree(ptr1);
 i=mallco_dev.perused();//?????
 ptr=(u8*)mymalloc(8*32);
 
 myfree(ptr2);
 i=mallco_dev.perused();//?????
 myfree(ptr3);
 i=mallco_dev.perused();//?????
 if(i)i=0;
 usmart_dev.init();
 OINT_COLOR=RED;      
   while(1) 
 {     
  LED0=!LED0;      
  delay_ms(500); 
 }               
}
*/